package com.dreamoriole.util;

import org.apache.log4j.Logger;
import org.hibernate.*;
import org.hibernate.cfg.*;

public class HibernateUtil {
	private static Configuration configuration;
	private static SessionFactory sessionFactory;
	private static ThreadLocal threadSession = new ThreadLocal();
	private static ThreadLocal threadTransaction = new ThreadLocal();
	private static Logger log = Logger.getLogger(HibernateUtil.class);
	
	static {
		try {
			configuration = new Configuration().configure(HibernateUtil.class.getResource("/com/dreamoriole/cfg/hibernate.cfg.xml"));
			sessionFactory = configuration.buildSessionFactory();
			
		} catch (HibernateException e) {
			log.error(e.getMessage());
			throw new ExceptionInInitializerError(e);
		}
	}
	
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public static Configuration getConfiguration() {
		return configuration;
	}
	
	/**
	 * 关闭Hibernate
	 * 
	 */
	public static void shutdown() {
		log.debug("关闭Hibernate！");
		
		getSessionFactory().close();
		
		//Clear static variable
		configuration = null;
		sessionFactory = null;
		
		//Clear ThreadLocal variable
		threadSession = null;
		threadTransaction = null;
	}
	
	/**
	 * 重建SessionFactory
	 *
	 */
	public static void rebuildSessionFactory() {
		log.debug("使用当前的Configuration重建SessionFactory。");
		rebuildSessionFactory(configuration);
	}
	
	/**
	 * 重建SessionFactory
	 * @param cfg
	 */
	public static void rebuildSessionFactory(Configuration cfg) {
		log.debug("使用给定的Configuration重建SessionFactory。");
		
		synchronized (sessionFactory) {
			if (sessionFactory != null && !sessionFactory.isClosed()) {
				sessionFactory.close();
			}
			
			sessionFactory = cfg.buildSessionFactory();
			configuration = cfg;
		}
	}
	
	/**
	 * 获得当前Session
	 * @return
	 */
	public static Session getCurrentSession() {
		Session s = (Session)threadSession.get();
		if (s == null) {
			log.debug("当前线程没有创建Session，SessionFactory为其新建Session。");
			s = getSessionFactory().openSession();
			threadSession.set(s);
		}
		else {
			s = getSessionFactory().getCurrentSession();
		}
		
		return s;
	}
	
	/**
	 * 关闭当前线程的Session
	 *
	 */
	public static void closeSession() {
		Session s = (Session)threadSession.get();
		threadSession.set(null);
		
		Transaction tx = (Transaction)threadTransaction.get();
		if (tx != null && (!tx.wasCommitted() || !tx.wasRolledBack())) {
			throw new IllegalStateException("关闭Session，但Transaction仍处于开启状态！");
		}
		else {
			log.debug("关闭当前线程的Session！");
			s.close();
		}
	}
	
	/**
	 * 开启一个事务
	 *
	 */
	public static void beginTransaction() {
		Transaction tx = (Transaction)threadTransaction.get();
		if (tx == null) {
			log.debug("为当前线程新建事务！");
			tx = getCurrentSession().beginTransaction();
			threadTransaction.set(tx);
		}
	}
	
	/**
	 * 提交事务
	 *
	 */
	public static void commitTransaction() {
		Transaction tx = (Transaction)threadTransaction.get();
		if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
			log.debug("提交事务！");
			tx.commit();
		}
		threadTransaction.set(null);
	}
	
	/**
	 * 回滚
	 *
	 */
	public static void rollbackTransaction() {
		Transaction tx = (Transaction)threadTransaction.get();
		threadTransaction.set(null);
		if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
			log.debug("尝试回滚事务！");
			tx.rollback();
			log.debug("回滚事务成功！");
		}
	}
}
